﻿package com.hxh.ocean.view{

	import com.fileitup.fisixengine.particles.CircleParticle;
	import com.fileitup.fisixengine.core.*;
	import com.hxh.ocean.events.*;
	import com.hxh.ocean.helpers.*;
	import com.hxh.utils.*;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.media.Sound;
	import flash.net.URLRequest;

	public class Bubble extends SuperObject {

		protected var _label:MovieClip;
		private var _radius:Number;

		private var _slope:Number;
		private var _moveDirection:Boolean;
		private var _playSFX:Boolean;
		private var _showLabel:Boolean;
		private var _mouseOver:Boolean;
		private var _color:uint;
		private var _scale:Number;
		private var _targetURL:String;
		
		private var _sfxPopIn:Sound;
		private var _sfxPopOut:Sound;
		
		private var _fisixContainer:CircleParticle;

		public function Bubble(bubbleName:String, sprite:MovieClip) {
			super();
			addEventListener(Event.ENTER_FRAME, startFrame);
			addEventListener(Events.BUBBLE_COLLIDES_BORDER, collideBorder);
			_playSFX = true;
			_showLabel = false;
			_sfxPopIn = new Sound(new URLRequest(Helper.SOUND_DROP));
			_sfxPopOut = new Sound(new URLRequest(Helper.SOUND_DRIP));
			buildAppearance(bubbleName, sprite);
			//showLabel();
			initVelocity();
		}

		public function get FisixContainer():CircleParticle
		{
			return _fisixContainer;
		}

		public function set FisixContainer(v:CircleParticle):void
		{
			_fisixContainer = v;
		}

		public function get Radius():Number
		{
			return _radius;
		}

		public function set Radius(v:Number):void
		{
			_radius = v;
		}

		public function get PlaySFX():Boolean
		{
			return _playSFX;
		}

		public function set PlaySFX(v:Boolean):void
		{
			_playSFX = v;
		}

		public function get ShowLabel():Boolean
		{
			return _showLabel;
		}

		public function set ShowLabel(v:Boolean):void
		{
			_showLabel = v;
			if (_showLabel){
				addLabel();
				_label.gotoAndPlay("MouseOver");
			}
			else{
				if (contains(_label)){
					_label.gotoAndPlay("MouseOut");
				}
			}
		}

		public function get StopMoving():Boolean
		{
			return _mouseOver;
		}

		public function set StopMoving(v:Boolean):void
		{
			_mouseOver = v;
		}
		
		/*********************** SETTERS / GETTERS *************************/

		public function get BaseColor():uint {
			return _color;
		}

		public function set BaseColor(color:uint):void {
			_color=color;
			_sprite.setBaseColor(color);
		}
		
		public function get HitArea():MovieClip{
			return _sprite.movClickArea;
		}
		
		public function set Scale(scale:Number):void {
			_scale = scale;
			_sprite.scaleX=scale;
			_sprite.scaleY=scale;
			_radius*=scale;
		}
		
		public function get Scale():Number{
			return _scale;
		}
		
		public function set Speed(speed:Number):void{
			_moveSpeed = speed;
		}
		
		public function get Speed():Number{
			return _moveSpeed;
		}
		
		public function set TargetURL(url:String):void{
			_targetURL = url;
		}
		
		public function get TargetURL():String{
			return _targetURL;
		}
		
		public function get BaseSprite():MovieClip{
			return _sprite.movBase;
		}

		private function startFrame(evt:Event):void {
			doUpdate();
		}
		
		protected function doUpdate():void{
			if (! _mouseOver) {
				//FisixContainer.active = true;
				/*moveAlongALine(_slope, _moveDirection);
				//Update effect and border collision
				updateEffects();
				var borderCollision:int=checkBorderCollision(_radius);
				if (borderCollision>0) {
					//Collided with the border
					dispatchEvent(new CollideBorder(Events.BUBBLE_COLLIDES_BORDER, borderCollision));
				}*/
				
			}
			else{

				
			}
		}

		/************************** PUBLIC METHODS *************************/

		/************************* PRIVATE METHODS *************************/

		protected function mouseIn(evt:MouseEvent):void {
			_sprite.gotoAndPlay("MouseOver");
			if (!_showLabel){
				addLabel();
				_label.gotoAndPlay("MouseOver");
			}
			_mouseOver=true;
			if (_playSFX){
				_sfxPopIn.play();
			}
		}

		protected function mouseAway(evt:MouseEvent):void {
			_sprite.gotoAndPlay("MouseOut");
			if (!_showLabel){
				_label.gotoAndPlay("MouseOut");	
			}
			_mouseOver=false;
			//Mouse.show();
		}
		
		private function mouseClick(evt:MouseEvent):void {
			dispatchEvent(new Event(Events.BUBBLE_CLICK));
		}

		private function initVelocity():void {
			//Initial velocity
			_moveSpeed=Maths.randomInt(5,10)/10;
			var angle:Number=Maths.randomInt(0,360);
			_slope=Math.tan(Maths.toRadian(angle));
			_moveDirection=Maths.randomInt(0,1000)<=500;
			_mouseOver=false;
		}
		

		public function popOut():void {
			_sprite.gotoAndPlay("PopOut");
			removeAllListeners();
			if (_playSFX){
				_sfxPopOut.play();
			}
		}

		public function popIn():void {
			_sprite.movBase.visible = true;
			_sprite.gotoAndPlay("PopIn");
			if (!_showLabel){
				addLabel();
				_label.gotoAndPlay("End");
			}
			addAllListeners();
			initVelocity();
			if (_playSFX){
				_sfxPopIn.play();
			}
		}
		
		public function removeAllListeners():void{
			HitArea.removeEventListener(MouseEvent.MOUSE_OVER, mouseIn);
			HitArea.removeEventListener(MouseEvent.MOUSE_OUT, mouseAway);
			HitArea.removeEventListener(MouseEvent.MOUSE_DOWN, mouseClick);
		}
		
		public function addAllListeners():void{
			HitArea.addEventListener(MouseEvent.MOUSE_OVER, mouseIn);
			HitArea.addEventListener(MouseEvent.MOUSE_OUT, mouseAway);
			HitArea.addEventListener(MouseEvent.MOUSE_DOWN, mouseClick);
		}

		protected function buildAppearance(bubbleName:String, sprite:MovieClip):void {
			_sprite = sprite;
			_scale = 1;
			_color = 0xFFFFFF;
			addChild(_sprite);
			addAllListeners();
			_sprite.addEventListener(Events.POPOUT_FINISH, popOutFinish);
			_label = new BubbleLabel();
			_label.setLabel(bubbleName);
			_label.addEventListener(Events.LABEL_FINISH, removeLabel);

			_radius=_sprite.width/2;
		}
		
		private function popOutFinish(evt:Event):void{
			dispatchEvent(new Event(Events.POPOUT_FINISH));
			if (parent!=null&&parent.contains(this)){
				parent.removeChild(this);
			}
			_sprite.movBase.visible = false;
		}
		
		protected function addLabel():void{
			addChild(_label);
			//_label.gotoAndPlay("MouseOver");
			_label.y = -_radius-10;
			//_label.x =15;
		}
		
		protected function removeLabel(evt:Event):void{
			removeChild(_label);
		}

		private function collideBorder(evt:CollideBorder):void {
			//Collision result
			var collisionResult:int=evt.CollisionResult;
			//Current moving angle
			var oldAngle:Number=Math.atan(_slope);
			//Reflect angle
			var newAngle:Number;
			//Moving left to right
			if (_moveDirection) {

				if (collisionResult==Helper.COLLIDE_RIGHT) {
					newAngle=Math.PI-oldAngle;
					_slope=Math.tan(newAngle);
					_moveDirection=false;
				} else if (collisionResult == Helper.COLLIDE_TOP) {
					newAngle=- oldAngle;
					_slope=Math.tan(newAngle);
				} else if (collisionResult == Helper.COLLIDE_BOTTOM) {
					newAngle=Math.PI-oldAngle;
					_slope=Math.tan(newAngle);
				}
			} else {

				if (collisionResult==Helper.COLLIDE_LEFT) {
					newAngle=- oldAngle;
					_slope=Math.tan(newAngle);
					_moveDirection=true;
				} else if (collisionResult == Helper.COLLIDE_TOP) {
					newAngle=Math.PI-oldAngle;
					_slope=Math.tan(newAngle);
				} else if (collisionResult == Helper.COLLIDE_BOTTOM) {
					newAngle=Math.PI-oldAngle;
					_slope=Math.tan(newAngle);
				}
			}
		}
	}

}